package org.example.aienglishapp_login.aspect.loginlog;

import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.example.aienglishapp_login.dto.login.UserLoginDTO;
import org.example.aienglishapp_login.entity.loginlog.LoginLog;
import org.example.aienglishapp_login.service.loginlog.LoginLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import eu.bitwalker.useragentutils.UserAgent;

import java.sql.Timestamp;
import java.util.Map;

@Aspect
@Component
public class LoginLogAspect {

    @Autowired
    private LoginLogService loginLogService;

    @Autowired
    private HttpServletRequest request;

    private static final Logger logger = LoggerFactory.getLogger(LoginLogService.class);

    // 获取地理位置
    public String getLocationByIp(String ipaddr) {
        String apiUrl = "https://ipapi.co/" + ipaddr + "/json/";
        RestTemplate restTemplate = new RestTemplate();

        try {
            ResponseEntity<Map> response = restTemplate.getForEntity(apiUrl, Map.class);
            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> locationData = response.getBody();
                String countryName = (String) locationData.get("country_name");
                if (countryName != null && !countryName.isEmpty()) {
                    return countryName;
                }
            }
        } catch (Exception e) {
            // 记录更详细的异常信息
            logger.error("获取地理位置失败: {}", e.getMessage(), e);
        }

        return "未知";
    }

    @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping) " +
            "&& execution(* org.example.aienglishapp_login.controller.login.UserController.loginUser(..))")
    public void loginMethods() {
    }

    @AfterReturning(pointcut = "loginMethods()", returning = "result")
    public void logSuccessLogin(JoinPoint joinPoint, Object result) {
        if (result instanceof ResponseEntity && ((ResponseEntity<?>) result).getStatusCode().is2xxSuccessful()) {
            Object[] args = joinPoint.getArgs();
            UserLoginDTO userLoginDTO = (UserLoginDTO) args[0];
            String username = userLoginDTO.getUsernameOrPhone();

            String ipaddr = request.getHeader("X-Forwarded-For");
            if (ipaddr == null || ipaddr.isEmpty()) {
                ipaddr = request.getRemoteAddr();
            }

            String location = "未知";
            if (!"0:0:0:0:0:0:0:1".equals(ipaddr) && !"127.0.0.1".equals(ipaddr)) {
                // 获取地理位置
                location = getLocationByIp(ipaddr);
            } else {
                System.out.println("本地请求，使用默认地理位置");
                location = "本地";
            }

            // 获取用户代理字符串
            String userAgent = request.getHeader("User-Agent");

            // 解析用户代理字符串
            UserAgent userAgentInfo = UserAgent.parseUserAgentString(userAgent);

            // 获取浏览器信息
            String browser = userAgentInfo.getBrowser().getName();
            String browserVersion = userAgentInfo.getBrowserVersion().getVersion();

            // 获取操作系统信息
            String os = userAgentInfo.getOperatingSystem().getName();

            LoginLog loginLog = new LoginLog();
            loginLog.setLoginName(username);
            loginLog.setIpaddr(ipaddr);
            loginLog.setLoginLocation(location);
            loginLog.setBrowser(browser + " " + browserVersion);
            loginLog.setOs(os);
            loginLog.setMsg("登录成功");
            loginLog.setStatus("success");
            loginLog.setLoginTime(new Timestamp(System.currentTimeMillis()));

            loginLogService.saveLoginLog(loginLog);
            System.out.println("登录成功日志已记录: " + loginLog);
        }
    }

    @AfterThrowing(pointcut = "loginMethods()", throwing = "ex")
    public void logFailedLogin(JoinPoint joinPoint, Exception ex) {
        Object[] args = joinPoint.getArgs();
        UserLoginDTO userLoginDTO = (UserLoginDTO) args[0];
        String username = userLoginDTO.getUsernameOrPhone();
        String ipaddr = request.getRemoteAddr();

        String location = "未知";
        if (!"0:0:0:0:0:0:0:1".equals(ipaddr) && !"127.0.0.1".equals(ipaddr)) {
            // 获取地理位置
            location = getLocationByIp(ipaddr);
        } else {
            System.out.println("本地请求，使用默认地理位置");
            location = "本地";
        }

        // 获取用户代理字符串
        String userAgent = request.getHeader("User-Agent");

        // 解析用户代理字符串
        UserAgent userAgentInfo = UserAgent.parseUserAgentString(userAgent);

        // 获取浏览器信息
        String browser = userAgentInfo.getBrowser().getName();
        String browserVersion = userAgentInfo.getBrowserVersion().getVersion();

        // 获取操作系统信息
        String os = userAgentInfo.getOperatingSystem().getName();

        LoginLog loginLog = new LoginLog();
        loginLog.setLoginName(username);
        loginLog.setIpaddr(ipaddr);
        loginLog.setLoginLocation(location);
        loginLog.setBrowser(browser + " " + browserVersion);
        loginLog.setOs(os);
        loginLog.setMsg("登录失败: " + ex.getMessage());
        loginLog.setStatus("failure");
        loginLog.setLoginTime(new Timestamp(System.currentTimeMillis()));

        loginLogService.saveLoginLog(loginLog);
        System.out.println("登录失败日志已记录: " + loginLog);
    }
}
